"""
    Custom Assertion Method Defined Here
"""
from typing import Text

from selenium.common import exceptions
from selenium.webdriver.support import expected_conditions as EC

from common.webKeys import HtmlPage
from utils.models import Locator


def assertTitleEquals(page: HtmlPage, title: Text):
    """检查页面标题是否正确

    :param page:
    :param title:
    :return:
    """
    current_title = page.getTitleText()
    assert title == current_title, f"Actual page title '{current_title}' does not match expected page title '{title}'."


def assertTitleContains(page: HtmlPage, titlePortion: Text):
    """检查页面标题是否包含指定文本

    :param page:
    :param titlePortion:
    :return:
    """
    current_title = page.getTitleText()
    assert titlePortion in current_title, f"Page title '{current_title}' does not contain the substring '{titlePortion}'."


def assertElementPresent(page: HtmlPage, locator: Locator):
    """检查页面元素是否存在

    :param page:
    :param locator:
    :return:
    """
    try:
        result = page.findElement(locator)
    except exceptions.NoSuchElementException:
        result = None

    err_msg = f"The page does not contain an element located by '{locator}'."
    assert result is not None, err_msg


def assertElementNotPresent(page: HtmlPage, locator: Locator):
    """检查页面元素是否不存在

    :param page:
    :param locator:
    :return:
    """
    try:
        result = page.findElement(locator)
    except exceptions.NoSuchElementException:
        result = None

    err_msg = f"The page contain an element located by '{locator}'."
    assert result is None, err_msg


def waitForElementPresent(page: HtmlPage, locator: Locator):
    """等待检查某元素是否存在

    :param page:
    :param locator:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until(EC.presence_of_element_located(locator))
    except exceptions.TimeoutException:
        result = None

    err_msg = f"The page does not contain an element located by '{locator}'."
    assert result is not None, err_msg


def assertUrlEquals(page: HtmlPage, url: Text):
    """检查当前url是否正确

    :param page:
    :param url:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until(EC.url_to_be(url))
    except exceptions.TimeoutException:
        result = False

    err_msg = f"Actual page url '{page.getCurrentUrl()}' does not equal expected url '{url}'."
    assert result is True, err_msg


def assertUrlChanges(page: HtmlPage, url: Text):
    """检查url是否发生改变

    :param page:
    :param url:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until(EC.url_changes(url))
    except exceptions.TimeoutException:
        result = False

    err_msg = f"Actual page url '{page.getCurrentUrl()}' equal expected url '{url}' has not changed."
    assert result is True, err_msg


def assertUrlMatches(page: HtmlPage, pattern: Text):
    """检查当前url是否包含或匹配某个内容

    :param page:
    :param pattern:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until(EC.url_matches(pattern))
    except exceptions.TimeoutException:
        result = False

    err_msg = f"Actual page url '{page.getCurrentUrl()}' does not match expected pattern '{pattern}'."
    assert result is True, err_msg


def assertTextParset(page: HtmlPage, text_: Text):
    """检查在当前给用户显示的页面上是否有出现指定的文本

    :param page:
    :param text_:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until(lambda driver: text_ in page.asText())
    except exceptions.TimeoutException:
        result = False

    err_msg = f"The page does not contain the text '{text_}'."
    assert result is True, err_msg


def assertTextNotParset(page: HtmlPage, text_: Text):
    """检查在当前给用户显示的页面上指定的文本是否已消失

    :param page:
    :param text_:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until_not(lambda driver: text_ in page.asText())
    except exceptions.TimeoutException:
        result = True

    err_msg = f"The page contains the text '{text_}'."
    assert result is False, err_msg


def assertTextParsetInElement(page: HtmlPage, locator: Locator, text_: Text):
    """检查指定元素是否出现指定的文本

    :param page:
    :param locator:
    :param text_:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until(EC.text_to_be_present_in_element(locator, text_))
    except exceptions.TimeoutException:
        result = False

    err_msg = f"The Element located by '{locator}' does not contain the text '{text_}'."
    assert result is True, err_msg


def assertTextNotParsetInElement(page: HtmlPage, locator: Locator, text_: Text):
    """检查指定元素的的指定的文本是否已消失

    :param page:
    :param locator:
    :param text_:
    :return:
    """
    try:
        result = page.explicit_wait(5, 1).until_not(EC.text_to_be_present_in_element(locator, text_))
    except exceptions.TimeoutException:
        result = True

    err_msg = f"The Element located by '{locator}' contains the text '{text_}'."
    assert result is False, err_msg
